// Copyright 2023 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "NetCommServer.h"

using namespace std;

/**
 * @功能描述：ServerNotice构造函数
 */
ServerNotice::ServerNotice(NetCommServer *server)
    : m_server(server)
{
}

/**
 * @功能描述：ServerNotice虚析构函数
 */
ServerNotice::~ServerNotice() {}//lint !e1540

/**
 * @功能描述：服务器监听socket异常回调通知，会重启Agent流程
 * @参数 [in] socket：服务端socket
 */
void ServerNotice::Notice(std::shared_ptr<VmiSocket> socket)
{
    if (socket != nullptr) {
        ERR("ServerNotice-----%p", socket.get());
    }
    if (m_server != nullptr) {
        m_server->HandleBreak();
    }
}

/**
 * @功能描述：VmiClientService构造函数
 */
VmiClientService::VmiClientService(NetCommServer *server)
    : m_server(server)
{
}

/**
 * @功能描述：VmiClientService析构函数
 */
VmiClientService::~VmiClientService()
{
    m_server = nullptr;
}//lint !e1540

/**
 * @功能描述：TCP服务端有新socket连接上时回调函数
 * @参数 [in] socket：新连接的客户端socket
 */
void VmiClientService::Callback(std::shared_ptr<VmiSocket> socket)
{
    INFO("VmiClientService callback");
    if (m_server != nullptr) {
        m_server->HandleConnect(socket);
    } else {
        ERR("error: m_server is nullptr");
    }
}

/**
 * @功能描述：构造函数
 * @参数 [in] port：端口
 * @参数 [in] eventCb：事件回调
 */
NetCommServer::NetCommServer(unsigned short port, std::shared_ptr<EventListener> listener)
    : m_status(NetCommServer::STATUS_IDLE), m_port(port), m_eventListener(listener)//lint !e1402
{
}//lint !e1401

/**
 * @功能描述：析构函数，释放对象
 */
NetCommServer::~NetCommServer()
{
    Stop();
}

/**
 * @功能描述：获取状态
 * @返回值：当前状态（空闲态/运行态）
 */
int NetCommServer::GetStatus()
{
    return m_status;
}

/**
 * @功能描述：设置端口
 * @参数 [in] port：端口
 * @返回值：成功返回true，失败返回false
 */
void NetCommServer::SetPort(unsigned short port)
{
    m_port = port;
}

/**
 * @功能描述：设置事件监听器
 */
void NetCommServer::SetEventListener(std::shared_ptr<EventListener> listener)
{
    m_eventListener = listener;
}

/**
 * @功能描述：处理新连接事件
 * @参数 [in] vmisocket：代表新连接的VmiSocket对象
 */
void NetCommServer::HandleConnect(std::shared_ptr<VmiSocket> vmisocket)
{
    if (vmisocket != nullptr) {
        INFO("RESTOREGL SetClientSocket %p", vmisocket.get());
        auto netComm = std::shared_ptr<NetComm>(new (std::nothrow) NetComm(vmisocket, nullptr));
        if (netComm == nullptr) {
            ERR("create NetComm for vmisocket failed");
            vmisocket = nullptr;
            return;
        }

        if (m_eventListener != nullptr) {
            m_eventListener->OnConnect(netComm);
        }
    } else {
        ERR("RESTOREGL error: vmisocket is nullptr");
    }
    INFO("RESTOREGL SetClientSocket end");
}

/**
 * @功能描述：处理server socket异常断开
 */
void NetCommServer::HandleBreak()
{
    if (m_eventListener != nullptr) {
        m_eventListener->OnBreak(shared_from_this());
    }
}

/**
 * @功能描述：启动通信监听服务端
 * @返回值：成功返回true，失败返回false
 */
bool NetCommServer::Start()
{
    INFO("begin to Start");
    if (m_status == NetCommServer::STATUS_RUNNING) {
        INFO("already running, if want restart, stop it first");
        return true;
    }

    bool result = false;
    do {
        m_serverNotice = std::shared_ptr<ServerNotice>(new (std::nothrow) ServerNotice(this));
        if (m_serverNotice == nullptr) {
            ERR("error: failed to create server notice");
            break;
        }

        m_clientServer = std::shared_ptr<VmiClientService>(new (std::nothrow) VmiClientService(this));
        if (m_clientServer == nullptr) {
            ERR("error: failed to create client server");
            break;
        }

        m_serverSocket = new (std::nothrow) VmiTcpServerSocket(INADDR_ANY,
            m_port, std::dynamic_pointer_cast<VmiServerService>(m_clientServer));
        if (m_serverSocket == nullptr) {
            ERR("error: failed to create TCP server socket");
            break;
        }

        m_serverSocket->SetEventNotice(std::dynamic_pointer_cast<VmiEventNotice>(m_serverNotice));
        if (m_serverSocket->Start() != 0) {
            ERR("error: failed to start TCP server!");
            break;
        }
        INFO("start TCP server successfully");

        result = true;
        m_status = NetCommServer::STATUS_RUNNING;
    } while (0);

    if (!result) {
        ERR("Start failed");
        Stop();
    }
    INFO("Start successed");
    return result;
}

/**
 * @功能描述：停止通信监听服务端
 */
void NetCommServer::Stop()
{
    INFO("Stop");
    if (m_serverSocket != nullptr) {
        m_serverSocket->SetEventNotice(nullptr);
        delete m_serverSocket;
        m_serverSocket = nullptr;
    }

    m_clientServer = nullptr;
    m_serverNotice = nullptr;
    m_status = NetCommServer::STATUS_IDLE;
}
